#include <iostream>
#include <set>
#include <cassert>
#include "HashTable.h"
#include "d_hashf.h"
#include "StopWatch.h"
using namespace std;
using namespace stdext; // to use the names in a set

// Simple main
int main( )
{
  const int NUMS = 100000;
  const int GAP  =   37;

 // load factor may be greather than 1 using separate chaining
  HashTable<int, hFintID> H(10000, 2.5);

  int i;
  StopWatch s;
  double sTime;

  cout << "Checking...\nStart inserting "
    << NUMS -1 << " items" << endl;

  s.start();
  // NUMS - 1 different items will be inserted
  for( i = GAP; i != 0; i = ( i + GAP ) % NUMS )
    H.insert( i );
  sTime = s.stop();

  cout << "Number of items inserted: " << H.size() << ", number of buckets: "
    << H.buckets() << ", and number of rehashing: " << H.reHashing()
    << ". Done in: " << sTime << " sec" << endl;

  cout << "Start succesful retrievals" << endl;

  s.start();
  for( i = GAP; i != 0; i = ( i + GAP ) % NUMS )
    assert(H.find( i ));
  sTime = s.stop();

  cout << "Succesful retrievals (the same items as before and in same order): "
    << sTime << " sec" << endl;

  s.start();
  for( i = 1; i < NUMS; i += 2 )
    H.erase( i );
  sTime = s.stop();
  cout << "After erase, number of items: " << H.size() << ", number of buckets: "
    << H.buckets() << ". Done in: " << sTime << " sec" << endl;


  for( i = 2; i < NUMS; i += 2 )
    if( !H.find( i ) )
      cout << "contains fails " << i << endl;

  for( i = 1; i < NUMS; i += 2 )
  {
    if( H.find( i ) )
      cout << "OOPS!!! " <<  i << endl;
  }

  // now do the same with a set (insert only)
  set<int> S;
  s.start();
  for( i = GAP; i != 0; i = ( i + GAP ) % NUMS )
    S.insert( i );
  sTime = s.stop();

  cout << "\n\nA set, number of items inserted: " << S.size()
    << ". Done in: " << sTime << " sec" << endl;

  s.start();
  for( i = GAP; i != 0; i = ( i + GAP ) % NUMS )
    S.find( i );
  sTime = s.stop();

  cout << "Succesful retreivals (the same items as before and in same order): "
    << sTime << " sec" << endl;

  system("PAUSE");
}
